﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using NHibernate;
using NHibernate.Criterion;


namespace Nhibernate
{
    public class HibernateDAO<T, IdT>
    {
        private ISession hSession;
        public List<T> getByCriterion()
        {
            ICriteria criteria = hSession.CreateCriteria(typeof(T));
            foreach (ICriterion criterion in expresstions)
                criteria.Add(criterion);
            return (List<T>)criteria.List<T>();
        }

        private ArrayList expresstions = new ArrayList();
        public void addSearchCriteria(ICriterion criterion)
        {
            if (criterion != null)
                expresstions.Add(criterion);
        }

        public HibernateDAO()
        {
            hSession = NHibernateSessionManager.sessionFactory.OpenSession();
        }

        public List<T> getBySQL(string sql)
        {
            List<T> lstTemp = new List<T>();
            ITransaction tran = null;
            try
            {
                tran = hSession.BeginTransaction();
                lstTemp = (List<T>)hSession.CreateSQLQuery(sql).AddEntity(typeof(T)).List<T>();
                tran.Commit();
            }
            catch (Exception e) { Console.WriteLine(e.Message); }
            finally { hSession.Flush(); hSession.Close(); }

            return lstTemp;

        }

        internal void SaveOrUpdate(T dm)
        {
            ITransaction tran = hSession.BeginTransaction();
            try
            {
                hSession.SaveOrUpdate(dm);
                tran.Commit();
            }
            catch (Exception ex)
            {
                tran.Rollback();
                throw ex;
            }
            finally
            {
                hSession.Close();
            }
        }

        // Execute a string sql
        internal void ExecuteSql(string strSql)
        {
            ITransaction tran = hSession.BeginTransaction();
            try
            {
                hSession.CreateSQLQuery(strSql).ExecuteUpdate();
                tran.Commit();
            }
            catch (Exception ex)
            {
                tran.Rollback();
                throw ex;
            }
            finally
            {
                hSession.Close();
            }
        }

        // get Entity by ID
        internal T GetById(IdT id)
        {

            return (T)hSession.Load(typeof(T), id);
        }

        // update Entity
        public T UpDate(T entity)
        {
            ITransaction tran = null;
            try
            {
                tran = hSession.BeginTransaction();
                hSession.Update(entity);
                tran.Commit();
            }
            catch (Exception e) { Console.WriteLine(e.Message); }
            finally { hSession.Flush(); hSession.Close(); }
            return entity;
        }

        // Save Entity
        public T Save(T entity)
        {
            ITransaction tran = null;
            try
            {
                tran = hSession.BeginTransaction();
                hSession.Save(entity);
                tran.Commit();
            }
            catch (Exception e) { Console.WriteLine(e.Message); }
            finally { hSession.Close(); }
            return entity;
        }

    

    }

    
}
